﻿using Common;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Threading;

namespace Device
{

    public class DM3058E
    {

        static List<KeyValuePair<Function, string>> ListSetFunctionCmd = new List<KeyValuePair<Function, string>>
            {
                new KeyValuePair<Function, string>( Function.DCV,":FUNCtion:VOLTage:DC"),
                new KeyValuePair<Function, string>( Function.ACV,":FUNCtion:VOLTage:AC"),
                new KeyValuePair<Function, string>( Function.DCI,":FUNCtion:CURRent:DC"),
                new KeyValuePair<Function, string>( Function.ACI,":FUNCtion:CURRent:AC"),
                new KeyValuePair<Function, string>( Function.WR2,":FUNCtion:RESistance"),
                new KeyValuePair<Function, string>( Function.WR4,":FUNCtion:FRESistance"),
                new KeyValuePair<Function, string>( Function.FREQ,":FUNCtion:FREQuency"),
                new KeyValuePair<Function, string>( Function.PERI,":FUNCtion:PERiod"),
                new KeyValuePair<Function, string>( Function.CONT,":FUNCtion:CONTinuity"),
                new KeyValuePair<Function, string>( Function.DIODE,":FUNCtion:DIODe"),
                new KeyValuePair<Function, string>( Function.CAP,":FUNCtion:CAPacitance")
            };

        static List<KeyValuePair<Function, string>> ListGetFunctionCmd = new List<KeyValuePair<Function, string>>
            {
                new KeyValuePair<Function, string>( Function.DCV,":MEASure:VOLTage:DC?"),
                new KeyValuePair<Function, string>( Function.ACV,":MEASure:VOLTage:AC?"),
                new KeyValuePair<Function, string>( Function.DCI,":MEASure:CURRent:DC?"),
                new KeyValuePair<Function, string>( Function.ACI,":MEASure:CURRent:AC?")
            };

        private const string StopCode = "\r\n";
        static bool connected = false;

        static SerialPort serialPort;
        private static string deviceName = "万用表DM3058E";
        private static string recvData;
        private static ManualResetEventSlim manualResetEventSlim;

        public static void Close()
        {
            serialPort?.Close();
            connected = false;
        }


        public static void Connect(string port, int baud = 9600)
        {
            if (connected) return;
            try
            {
                serialPort = new SerialPort();
                serialPort.BaudRate = baud;
                serialPort.PortName = port;
                serialPort.Open();
                serialPort.DataReceived += SerialPort_DataReceived;
                //SendCmd(CmdOpenCurrentDC);
                connected = true;
            }
            catch (Exception)
            {
                throw new Exception($"{deviceName}连接错误");
            }
        }

        private static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            {
                recvData = null;
                recvData = (sender as SerialPort).ReadLine();
                if (!string.IsNullOrEmpty(recvData))
                {
                    manualResetEventSlim.Set();
                    Mylog.Debug($"{deviceName}  [{recvData}]");
                }
            }
        }

        private static void SendCmd(string cmd)
        {
            Mylog.Debug($"{deviceName} [{cmd}]");
            serialPort.Write(cmd + StopCode);
        }

        private static string SendCmdAndWaitReturn(string cmd)
        {
            Mylog.Debug(deviceName + cmd);
            var sendCmd = cmd + StopCode;
            manualResetEventSlim = new ManualResetEventSlim(false);
            serialPort.Write(sendCmd);
            if (!manualResetEventSlim.Wait(5000))
            {
                throw new Exception("电源表通信异常");
            }
            return recvData;
        }

        /// <summary>
        /// 读取的当前设备状态
        /// </summary>
        /// <returns></returns>
        public static Function GetFunction()
        {
            string result = SendCmdAndWaitReturn(":FUNCtion?");
            if (result == "2WR")
            {
                result = "WR2";
            }
            else if (result == "4WR")
            {
                result = "WR4";
            }
            if (result != null)
            {
                foreach (Function items in Enum.GetValues(typeof(Function)))
                {

                    if (result == items.ToString())
                    {
                        return items;
                    }
                }
            }
            return 0;
        }
        /// <summary>
        /// 设置当前万用表功能
        /// </summary>
        /// <param name="func"></param>
        /// <exception cref="Exception"></exception>
        public static void SetFunction(Function func)
        {
            string cmd = ListSetFunctionCmd.Where(x => x.Key == func).First().Value;
            //string cmd = ListSetFunctionCmd.FirstOrDefault(x => x.Key == func).Value;
            SendCmd(cmd);
            Thread.Sleep(100);
            if (func != GetFunction())
            {
                throw new Exception($"{deviceName} 设置{func}功能异常");
            }
        }

        /// <summary>
        /// 获取当前功能状态的值
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static double GetValue(Function func)
        {
            //var tmp = GetFunction();
            //if (func != tmp)
            //{
            //    SetFunction(func);
            //}
            //else
            //{
            //    throw new Exception($"{deviceName} 读取{func}功能异常");
            //}
            string cmd = ListGetFunctionCmd.FirstOrDefault(x => x.Key == func).Value;
            double result = double.Parse(SendCmdAndWaitReturn(cmd));
            return result;
        }


    }
}